package com.sky.aspect;

import com.sky.anno.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 公共字段自动填充切面类
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    /**
     * 切入点表达式：扫描mapper中所有有anno注解的方法
     * @param joinPoint
     */
    @Before("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.anno.AutoFill)")
    public void autoFill(JoinPoint joinPoint) throws Exception{
        //1获取mapper执行方法的参数
        Object arg = joinPoint.getArgs()[0];

        //2给实体类的四个属性赋值
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        //获取方法上的指定注解
        AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);

        if (annotation.value()== OperationType.INSERT){
            // 实体类给4个属性赋值
            Method method1 = arg.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
            Method method2 = arg.getClass().getDeclaredMethod("setCreateUser", Long.class);
            Method method3 = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
            Method method4 = arg.getClass().getDeclaredMethod("setUpdateUser", Long.class);

            //运行四个方法
              method1.invoke(arg,LocalDateTime.now());
              method3.invoke(arg,LocalDateTime.now());
              method2.invoke(arg, BaseContext.getCurrentId());
              method4.invoke(arg, BaseContext.getCurrentId());
        }
        if (annotation.value()==OperationType.UPDATE){
            //给2个属性复制
            Method method3 = arg.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
            Method method4 = arg.getClass().getDeclaredMethod("setUpdateUser", Long.class);

            method3.invoke(arg,LocalDateTime.now());
            method4.invoke(arg, BaseContext.getCurrentId());

        }
    }

}
